// author: Moser Michael (SWD09)
// date: 2011-12-14
// homework 4: race conditions

#include <stdlib.h>
#include <pthread.h>
#include <iostream>

using namespace std;

void* calculate_int(void* ptr);

class Integer
{
public:
    Integer()
    {
        i_ = 0;
        pthread_mutex_init(&lock_, NULL);
    }
    ~Integer()
    {
        pthread_mutex_destroy(&lock_);
    }

    void increment()
    {
        pthread_mutex_lock(&lock_);
        i_++;
        pthread_mutex_unlock(&lock_);
    }

    int get() const
    {
        return i_;
    }

private:
    // C++ inserts automatic copying otherwise which doesn't make
    // sense for the mutex member.
    Integer(const Integer&);
    Integer& operator=(const Integer&);

private:
    int i_;
    pthread_mutex_t lock_;
};

int main(int argc, char **argv)

{
     pthread_t thread1, thread2;
     Integer i;

     pthread_create( &thread1, NULL, calculate_int, &i);
     pthread_create( &thread2, NULL, calculate_int, &i);

 
     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     cout << i.get() << endl;

     exit(0);
}

void* calculate_int(void* ptr)
{

     Integer* j = (Integer*) ptr;  
     int k = 0;
     for (; k <10000000; k++)
         j->increment();
}
